home *** CD-ROM | disk | FTP | other *** search
/ Experimental BBS Explossion 3 / Experimental BBS Explossion III.iso / games / nhak_src.zip / AMIWIND.C < prev    next >
C/C++ Source or Header  |  1993-03-16  |  18KB  |  694 lines

  1. /*
  2.  *  amiwind.c    (C) Copyright 1989 by Olaf Seibert (KosmoSoft)
  3.  */
  4. /* NetHack may be freely redistributed.  See license for details. */
  5.  
  6. /*
  7.  *  Here is some very Amiga specific stuff, dealing with
  8.  *  screens, windows, menus, and input via IntuiMessages.
  9.  */
  10.  
  11. #include "hack.h"
  12.  
  13. #undef TRUE
  14. #undef FALSE
  15. #undef COUNT
  16. #undef NULL
  17.  
  18. #include <exec/types.h>
  19. #include <exec/alerts.h>
  20. #include <exec/io.h>
  21. #include <exec/devices.h>
  22. #include <devices/console.h>
  23. #include <devices/conunit.h>
  24. #include <intuition/intuition.h>
  25. #include <libraries/dosextens.h>
  26.  
  27. #ifdef LATTICE
  28. #include <dos.h>
  29. #include <proto/exec.h>
  30. #include <proto/graphics.h>
  31. #include <proto/intuition.h>
  32. #include <proto/diskfont.h>
  33. #include <proto/console.h>
  34. #endif
  35.  
  36. #include "Amiga:amimenu.c"
  37.  
  38. /*
  39.  * Versions we need of various libraries.  We can't use LIBRARY_VERSION
  40.  * as defined in <exec/types.h> because some of the libraries we need
  41.  * don't have that version number in the 1.2 ROM.
  42.  */
  43.  
  44. #define INTUITION_VERSION 33L
  45. #define GRAPHICS_VERSION  33L
  46. #define DISKFONT_VERSION  34L
  47. #define ICON_VERSION      34L
  48.  
  49. /*  First, external declarations... */
  50.  
  51. extern struct Library *IconBase;
  52. struct Library *ConsoleDevice;
  53.  
  54. #ifdef AZTEC_C
  55. void FDECL(Alert, (long, char *));
  56. void NDECL(Forbid);
  57. void NDECL(Permit);
  58. struct Process *FDECL(FindTask, (char *));
  59. struct Library *FDECL(OpenLibrary, (char *, long));
  60. void FDECL(CloseLibrary, (struct Library *));
  61. struct Message *FDECL(GetMsg, (struct MsgPort *));
  62. void FDECL(ReplyMsg, (struct Message *));
  63. long FDECL(OpenDevice, (char *, long, struct IORequest *, long));
  64. void FDECL(CloseDevice, (struct IORequest *));
  65. long FDECL(DoIO, (struct IORequest *));
  66. struct TextFont *FDECL(OpenDiskFont, (struct TextAttr *));
  67. struct TextFont *FDECL(OpenFont, (struct TextAttr *));
  68. void FDECL(CloseFont, (struct TextFont *));
  69. void FDECL(LoadRGB4, (struct ViewPort *, unsigned short *, long));
  70. long FDECL(SetFont, (struct RastPort *, struct TextFont*));
  71. struct MsgPort *FDECL(CreatePort, (char *, long));
  72. void FDECL(DeletePort, (struct MsgPort *));
  73. struct Screen *FDECL(OpenScreen, (struct NewScreen *));
  74. struct Window *FDECL(OpenWindow, (struct NewWindow *));
  75. void FDECL(CloseWindow, (struct Window *));
  76. void FDECL(SetMenuStrip, (struct Window *, struct Menu *));
  77. void FDECL(ClearMenuStrip, (struct Window *));
  78. struct MenuItem *FDECL(ItemAddress, (struct Menu *, long));
  79. long FDECL(RawKeyConvert, (struct InputEvent *, char *, long, struct KeyMap *));
  80. #endif
  81.  
  82. static int NDECL(BufferGetchar);
  83. static void FDECL(ConvertKey, (register struct IntuiMessage *));
  84. static void FDECL(ProcessMessage, (register struct IntuiMessage *));
  85. #ifdef AMIFLUSH
  86. static struct Message *FDECL(GetFMsg,(struct MsgPort *));
  87. #endif
  88. void NDECL(Initialize);
  89.  
  90. /*  Now our own variables */
  91.  
  92. struct Library *IntuitionBase;
  93. struct Screen *HackScreen;
  94. struct Window *HackWindow;
  95. struct Window *pr_WindowPtr;
  96. struct IOStdReq ConsoleIO;
  97. char Initialized = 0;
  98.  
  99. #ifdef HACKFONT
  100. struct Library *GfxBase;
  101. struct Library *DiskfontBase;
  102. #endif
  103.  
  104. extern struct Library *ConsoleDevice;
  105.  
  106. #define CSI        '\x9b'
  107. #define NO_CHAR     -1
  108. #define RAWHELP     0x5F    /* Rawkey code of the HELP key */
  109.  
  110. /*
  111.  *  It is assumed that all multiple-character outputs are
  112.  *  at most CONBUFFER characters each.
  113.  */
  114.  
  115. #define CONBUFFER   512
  116. static char ConsoleBuffer[CONBUFFER];
  117. static unsigned short Buffered;
  118.  
  119. #define KBDBUFFER   10
  120. static unsigned char KbdBuffer[KBDBUFFER];
  121. static unsigned char KbdBuffered;
  122.  
  123. #define BufferQueueChar(ch) (KbdBuffer[KbdBuffered++] = ch)
  124.  
  125. /*
  126.  *  It seems Intuition won't OpenDiskFont our diskFont, so we get the
  127.  *  closest match, which is of course topaz/8. (and if not, it is still
  128.  *  an 8-pixel font, so everything still looks ok)
  129.  */
  130.  
  131. #ifdef HACKFONT
  132.  
  133. struct TextFont *HackFont;
  134. UBYTE FontName[] = "NetHack:hack.font";
  135. #define         SIZEOF_DISKNAME    8
  136.  
  137. #endif
  138.  
  139. struct TextAttr Hack80 = {
  140. #ifdef HACKFONT
  141.     &FontName[SIZEOF_DISKNAME],
  142. #else
  143.     (UBYTE *) "topaz.font",
  144. #endif
  145.     TOPAZ_EIGHTY, FS_NORMAL, FPF_DISKFONT | FPF_ROMFONT
  146. };
  147.  
  148. #define BARHEIGHT    11
  149. #define WINDOWHEIGHT    192
  150. #define WIDTH        640
  151.  
  152. #ifdef TEXTCOLOR
  153. #define DEPTH       3
  154. static unsigned short palette[] = {
  155.     0x0000,    /* Black   */
  156.     0x0DDD, /* White   */
  157.         0x0C75, /* Brown   */
  158.     0x0B08,    /* Cyan    */
  159.     0x00B0,    /* Green   */
  160.     0x0F08,    /* Magenta */
  161.     0x055F,    /* Blue    */
  162.     0x0F00,    /* Red     */
  163. };
  164. #else
  165. #define DEPTH        2
  166. #endif
  167.  
  168. struct NewScreen NewHackScreen = {
  169.     0, 0, WIDTH, BARHEIGHT + WINDOWHEIGHT, DEPTH,
  170.     0, 1,     /* DetailPen, BlockPen */
  171.     HIRES,
  172.     CUSTOMSCREEN,
  173.     &Hack80,  /* Font */
  174.     (UBYTE *) " NetHack 3.0 - Ported by Olaf Seibert (KosmoSoft)",
  175.     NULL,     /* Gadgets */
  176.     NULL,     /* CustomBitmap */
  177. };
  178.  
  179. struct NewWindow NewHackWindow = {
  180.     /* left, top, width, height, detailpen, blockpen */
  181.     0, BARHEIGHT, WIDTH, WINDOWHEIGHT, -1, -1,
  182.     RAWKEY | MENUPICK
  183. #ifdef MAIL
  184.               | DISKINSERTED
  185. #endif
  186.     , BORDERLESS | BACKDROP | ACTIVATE,
  187.     NULL, NULL, NULL,
  188.     NULL, NULL, -1,-1,-1,-1, CUSTOMSCREEN
  189. };
  190.  
  191. static int BufferGetchar()
  192. {
  193.     register unsigned char *from, *to;
  194.     register int c;
  195.     register short i;
  196.  
  197.     if (KbdBuffered) {
  198.     c = KbdBuffer[0];
  199.     KbdBuffered--;
  200.     to = KbdBuffer;
  201.     from = to + 1;
  202.     /* Move the remaining characters */
  203.     for (i = KbdBuffered; i > 0; i--) {
  204.         *to++ = *from++;
  205.     }
  206.     return c;
  207.     }
  208.  
  209.     return NO_CHAR;
  210. }
  211.  
  212. /*
  213.  *  This should remind you remotely of DeadKeyConvert,
  214.  *  but we are cheating a bit.
  215.  *  We want complete control over the numeric keypad, and no
  216.  *  dead keys... (they are assumed to be on Alted keys)
  217.  *  Also assumed is that the IntuiMessage is of type RAWKEY.
  218.  *  For some reason, IECODE_UP_PREFIX events seem to be lost when they
  219.  *  occur while our console window is inactive. This is particulary
  220.  *  troublesome with qualifier keys... Is this because I never
  221.  *  RawKeyConvert those events???
  222.  */
  223.  
  224. static void ConvertKey(message)
  225. register struct IntuiMessage *message;
  226. {
  227.     static struct InputEvent theEvent;
  228.     static char       numpad[] = "bjnh.lyku";
  229.     static char  ctrl_numpad[] = "\x02\x0A\x0E\x08.\x0C\x19\x0B\x15";
  230.     static char shift_numpad[] = "BJNH.LYKU";
  231.  
  232.     unsigned char buffer[1];
  233.     register char length;
  234.     register ULONG qualifier = message->Qualifier;
  235.     char numeric_pad, shift, control, alt;
  236.  
  237.     control = (qualifier &  IEQUALIFIER_CONTROL) != 0;
  238.     shift   = (qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT)) != 0;
  239.     alt     = (qualifier & (IEQUALIFIER_LALT   | IEQUALIFIER_RALT  )) != 0;
  240.     /* Allow ALT to function as a META key ... */
  241.     qualifier &= ~(IEQUALIFIER_LALT | IEQUALIFIER_RALT);
  242.     numeric_pad = (qualifier & IEQUALIFIER_NUMERICPAD) != 0;
  243.  
  244.     /*
  245.      *    Shortcut for HELP and arrow keys. I suppose this is allowed.
  246.      *    The defines are in intuition/intuition.h, and the keys don't
  247.      *    serve 'text' input, normally. Also, parsing their escape
  248.      *    sequences is such a mess...
  249.      */
  250.  
  251.     switch (message->Code) {
  252.     case RAWHELP:
  253.     length = '?';
  254.     goto no_arrow;
  255.     case CURSORLEFT:
  256.     length = 'h'; goto arrow;
  257.     case CURSORDOWN:
  258.     length = 'j'; goto arrow;
  259.     case CURSORUP:
  260.     length = 'k'; goto arrow;
  261.     case CURSORRIGHT:
  262.     length = 'l';
  263.     arrow:
  264.     if (!flags.num_pad)    /* Give digits if set, letters otherwise */
  265.         goto wasarrow;
  266.     no_arrow:
  267.     BufferQueueChar(length);
  268.     return;
  269.     }
  270.  
  271. #ifdef BETA
  272.     if (!ConsoleDevice) { /* Should never happen */
  273.     Abort(AG_IOError | AO_ConsoleDev);
  274.     return;
  275.     }
  276. #endif
  277.  
  278.     theEvent.ie_Class = IECLASS_RAWKEY;
  279.     theEvent.ie_Code = message->Code;
  280.     theEvent.ie_Qualifier = numeric_pad ? IEQUALIFIER_NUMERICPAD :
  281.                       qualifier;
  282.     theEvent.ie_EventAddress = (APTR) *(message->IAddress);
  283.  
  284.     length = RawKeyConvert(&theEvent, buffer, (long) sizeof(buffer), NULL);
  285.  
  286.     if (length == 1) {   /* Plain ASCII character */
  287.     length = buffer[0];
  288.     if (!flags.num_pad && numeric_pad && length >= '1' && length <= '9') {
  289. wasarrow:
  290.         length -= '1';
  291.         if (control) {
  292.         length = ctrl_numpad[length];
  293.         } else if (shift) {
  294.         length = shift_numpad[length];
  295.         } else {
  296.         length = numpad[length];
  297.         }
  298.     }
  299.     if (alt)
  300.         length |= 0x80;
  301.     BufferQueueChar(length);
  302.     } /* else shift, ctrl, alt, amiga, F-key, shift-tab, etc */
  303. }
  304.  
  305. /*
  306.  *  Process an incoming IntuiMessage.
  307.  *  It would certainly look nicer if this could be done using a
  308.  *  PA_SOFTINT message port, but we cannot call RawKeyConvert()
  309.  *  during a software interrupt.
  310.  *  Anyway, kbhit() is called often enough, and usually gets
  311.  *  ahead of input demands, when the user types ahead.
  312.  */
  313.  
  314. static void ProcessMessage(message)
  315. register struct IntuiMessage *message;
  316. {
  317.     switch(message->Class) {
  318.     case MENUPICK:
  319.     {
  320.         USHORT thismenu;
  321.         struct MenuItem *item = NULL;
  322.  
  323.         thismenu = message->Code;
  324.         while (thismenu != MENUNULL) {
  325.         item = ItemAddress(HackMenu, (ULONG) thismenu);
  326.         if (KbdBuffered < KBDBUFFER)
  327.             BufferQueueChar(item->Command); /* Unused: No COMMSEQ */
  328.         thismenu = item->NextSelect;
  329.         }
  330.     }
  331.     break;
  332.     case RAWKEY:
  333.     if (!(message->Code & IECODE_UP_PREFIX))
  334.         ConvertKey(message);    /* May queue multiple characters */
  335.     break;                /* but doesn't do that yet       */
  336. #ifdef MAIL
  337.     case DISKINSERTED:
  338.     {
  339.         extern int mustgetmail;
  340.  
  341.         if (mustgetmail < 0)
  342.         mustgetmail = rn1(100,50);
  343.     }
  344. #endif
  345.     }
  346.     ReplyMsg((struct Message *) message);
  347. }
  348.  
  349. /*
  350.  *  Get all incoming messages and fill up the keyboard buffer,
  351.  *  thus allowing Intuition to (maybe) free up the IntuiMessages.
  352.  *  Return when no more messages left, or keyboard buffer half full.
  353.  *  We need to do this since there is no one-to-one correspondence
  354.  *  between characters and incoming messages.
  355.  */
  356.  
  357. int kbhit()
  358. {
  359.     register struct IntuiMessage *message;
  360.  
  361.     while( (KbdBuffered < KBDBUFFER / 2) &&
  362. #ifdef AMIFLUSH
  363.         (message = (struct IntuiMessage *) GetFMsg(HackWindow->UserPort)))
  364. #else
  365.         (message = (struct IntuiMessage *) GetMsg(HackWindow->UserPort)) )
  366. #endif
  367.     ProcessMessage(message);
  368.  
  369.     return (int) KbdBuffered;
  370. }
  371.  
  372. /*
  373.  *  Get a character from the keyboard buffer, waiting if
  374.  *  not available.
  375.  */
  376.  
  377. int WindowGetchar()
  378. {
  379.     while (!kbhit()) {
  380.     WaitPort(HackWindow->UserPort);
  381.     }
  382.     return BufferGetchar();
  383. }
  384.  
  385. /*
  386.  *  Flush the output waiting in the console output buffer.
  387.  */
  388.  
  389. void WindowFlush()
  390. {
  391. #ifdef BETA
  392.     if (!ConsoleDevice) { /* Should never happen */
  393.     Abort(AG_IOError | AO_ConsoleDev);
  394.     return;
  395.     }
  396. #endif
  397.  
  398.     if (Buffered) {
  399.     ConsoleIO.io_Command = CMD_WRITE;
  400.     ConsoleIO.io_Data = (APTR)ConsoleBuffer;
  401.     ConsoleIO.io_Length = Buffered;
  402.     DoIO((struct IORequest *) &ConsoleIO);
  403.     Buffered = 0;
  404.     }
  405. }
  406.  
  407. /*
  408.  *  Queue a single character for output to the console screen.
  409.  */
  410.  
  411. void WindowPutchar(c)
  412. char c;
  413. {
  414.     if (Buffered >= CONBUFFER)
  415.     WindowFlush();
  416.  
  417.     ConsoleBuffer[Buffered++] = c;
  418. }
  419.  
  420. /*
  421.  *  Queue an entire string for output to the console screen,
  422.  *  flushing the existing characters first, if necessary.
  423.  *  Do not append a newline.
  424.  */
  425.  
  426. void WindowFPuts(string)
  427. char *string;
  428. {
  429.     register int len = strlen(string);
  430.  
  431.     if (len + Buffered >= CONBUFFER)
  432.     WindowFlush();
  433.  
  434.     strcpy(ConsoleBuffer + Buffered, string);
  435.     Buffered += len;
  436. }
  437.  
  438. /*
  439.  *  Queue an entire string for output to the console screen,
  440.  *  flushing the existing characters first, if necessary.
  441.  *  Append a newline.
  442.  */
  443.  
  444. void WindowPuts(string)
  445. char *string;
  446. {
  447.     WindowFPuts(string);
  448.     WindowPutchar('\n');
  449. }
  450.  
  451. /*
  452.  *  Queue a formatted string for output to the console screen,
  453.  *  flushing the existing characters first, if necessary.
  454.  */
  455.  
  456. /*VARARGS1*/
  457. #if defined(USE_STDARG) || defined(USE_VARARGS)
  458. void
  459. WindowPrintf VA_DECL(char *, fmt)
  460.     VA_START(fmt);
  461.     VA_INIT(fmt, char *);
  462.     WindowFlush();  /* Don't know if all will fit */
  463.     vsprintf(ConsoleBuffer, fmt, VA_ARGS);
  464.     ConsoleIO.io_Command = CMD_WRITE;
  465.     ConsoleIO.io_Data = (APTR)ConsoleBuffer;
  466.     ConsoleIO.io_Length = -1;
  467.     DoIO((struct IORequest *) &ConsoleIO);
  468.     VA_END();
  469. }
  470. #else
  471. void WindowPrintf(fmt, args, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
  472. char *fmt;
  473. long args, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9;
  474. {
  475. # ifdef AZTEC_36     /* Efficient but not portable */
  476.     format(WindowPutchar, fmt, &args);
  477. #else
  478.     WindowFlush();  /* Don't know if all will fit */
  479.     sprintf(ConsoleBuffer, fmt, args, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9);
  480.     ConsoleIO.io_Command = CMD_WRITE;
  481.     ConsoleIO.io_Data = (APTR)ConsoleBuffer;
  482.     ConsoleIO.io_Length = -1;
  483.     DoIO((struct IORequest *) &ConsoleIO);
  484. #endif
  485. }
  486. #endif
  487.  
  488. /*
  489.  *  Clean up everything. But before we do, ask the user to hit return
  490.  *  when there is something that s/he should read.
  491.  */
  492.  
  493. void CleanUp()
  494. {
  495.     /* Clean up resources */
  496.     if (ConsoleIO.io_Device) {
  497.     register struct ConUnit *cu;
  498.  
  499.     cu = (struct ConUnit *)ConsoleIO.io_Unit;
  500.     if (cu->cu_XCCP != 1 || cu->cu_YCCP != 1)
  501.         getret();
  502.  
  503.     CloseDevice((struct IORequest *) &ConsoleIO);
  504.     ConsoleDevice = NULL;
  505.     }
  506.     if (ConsoleIO.io_Message.mn_ReplyPort)
  507.     DeletePort(ConsoleIO.io_Message.mn_ReplyPort);
  508.     if (HackWindow) {
  509.     register struct IntuiMessage *msg;
  510.  
  511.     ((struct Process *) FindTask(NULL))->pr_WindowPtr = (APTR) pr_WindowPtr;
  512.     ClearMenuStrip(HackWindow);
  513.     Forbid();
  514.     while (msg = (struct IntuiMessage *) GetMsg(HackWindow->UserPort))
  515.         ReplyMsg((struct Message *) msg);
  516.     CloseWindow(HackWindow);
  517.     Permit();
  518.     HackWindow = NULL;
  519.     }
  520.     if (HackScreen) {
  521.     CloseScreen(HackScreen);
  522.     HackScreen = NULL;
  523.     }
  524.     if (IconBase) {
  525.     CloseLibrary(IconBase);
  526.     IconBase = NULL;
  527.     }
  528. #ifdef HACKFONT
  529.     if (HackFont) {
  530.     CloseFont(HackFont);
  531.     HackFont = NULL;
  532.     }
  533.     if (DiskfontBase) {
  534.     CloseLibrary(DiskfontBase);
  535.     DiskfontBase = NULL;
  536.     }
  537.     if (GfxBase) {
  538.     CloseLibrary(GfxBase);
  539.     GfxBase = NULL;
  540.     }
  541. #endif
  542.     if (IntuitionBase) {
  543.     CloseLibrary(IntuitionBase);
  544.     IntuitionBase = NULL;
  545.     }
  546.  
  547.     Initialized = 0;
  548. }
  549.  
  550. void Abort(rc)
  551. long rc;
  552. {
  553. #ifdef CHDIR
  554.     extern char orgdir[];
  555.     chdir(orgdir);
  556. #endif
  557.     if (Initialized && ConsoleDevice) {
  558.     printf("\n\nAbort with alert code %08lx...\n", rc);
  559.     getret();
  560.     } else
  561.     Alert(rc, 0L);
  562. #ifdef LATTICE
  563.     {
  564. /*    __emit(0x4afc);        /* illegal instruction */
  565.     __emit(0x40fc);        /* divide by */
  566.     __emit(0x0000);        /*  #0    */
  567.         /* NOTE: don't move CleanUp() above here - */
  568.         /* it is too likely to kill the system     */
  569.         /* before it can get the SnapShot out, if  */
  570.         /* there is something really wrong.       */
  571. __builtin_printf("abort botch");                /* (KL)TEMP */
  572.     }
  573. #endif
  574.     CleanUp();
  575. #undef exit
  576. #ifdef AZTEC_C
  577.     _abort();
  578. #endif
  579.     exit((int) rc);
  580. }
  581.  
  582. /*
  583.  *  Open everything we need.
  584.  */
  585.  
  586. void Initialize()
  587. {
  588.     if (Initialized)
  589.     return;
  590.  
  591.     if ( (IntuitionBase = OpenLibrary("intuition.library", INTUITION_VERSION))
  592.       == NULL)
  593.     Abort(AG_OpenLib | AO_Intuition);
  594.  
  595. #ifdef HACKFONT
  596.  
  597.     if ( (GfxBase = OpenLibrary("graphics.library", GRAPHICS_VERSION)) == NULL)
  598.     Abort(AG_OpenLib | AO_GraphicsLib);
  599.  
  600.     /*
  601.      *    Force our own font to be loaded, if possible.
  602.      *    If we can open diskfont.library, but not our font, we can close
  603.      *    the diskfont.library again since it just wastes memory.
  604.      *    Even if we can open the font, we don't need the diskfont.library
  605.      *    anymore, since CloseFont is a graphics.library function.
  606.      */
  607.  
  608.     if ((HackFont = OpenFont(&Hack80)) == NULL) {
  609.     if (DiskfontBase = OpenLibrary("diskfont.library", DISKFONT_VERSION)) {
  610.         Hack80.ta_Name -= SIZEOF_DISKNAME;
  611.         HackFont = OpenDiskFont(&Hack80);
  612.         Hack80.ta_Name += SIZEOF_DISKNAME;
  613.         CloseLibrary(DiskfontBase);
  614.         DiskfontBase = NULL;
  615.     }
  616.     }
  617. #endif
  618.  
  619.     /* if ( (IconBase = OpenLibrary("icon.library", ICON_VERSION)) == NULL)
  620.     Abort(AG_OpenLib | AO_IconLib); */
  621.  
  622.     /*
  623.      *    Now Intuition is supposed to use our HackFont for the screen,
  624.      *    since we have a corresponding TextAttr, but it *doesn't*.
  625.      *    So, we need to do a SetFont() a bit later on.
  626.      */
  627.     if ( (HackScreen = OpenScreen(&NewHackScreen)) == NULL)
  628.     Abort(AN_OpenScreen & ~AT_DeadEnd);
  629.  
  630. #ifdef TEXTCOLOR
  631.     LoadRGB4(&HackScreen->ViewPort, palette, 8L);
  632. #endif
  633.  
  634.     NewHackWindow.Screen = HackScreen;
  635.  
  636.     if ( (HackWindow = OpenWindow(&NewHackWindow)) == NULL)
  637.     Abort(AN_OpenWindow & ~AT_DeadEnd);
  638.  
  639.     SetMenuStrip(HackWindow, HackMenu);
  640.     {
  641.     register struct Process *myProcess = (struct Process *) FindTask(NULL);
  642.     pr_WindowPtr = (struct Window *)myProcess->pr_WindowPtr;
  643.     myProcess->pr_WindowPtr = (APTR) HackWindow;
  644.     }
  645. #ifdef HACKFONT
  646.     if (HackFont)
  647.     SetFont(HackWindow->RPort, HackFont);
  648. #endif
  649.  
  650.     ConsoleIO.io_Data = (APTR) HackWindow;
  651.     ConsoleIO.io_Length = sizeof(*HackWindow);
  652.     ConsoleIO.io_Message.mn_ReplyPort = CreatePort(NULL, 0L);
  653.     if (OpenDevice("console.device", 0L, (struct IORequest *) &ConsoleIO, 0L) != 0)
  654.     Abort(AG_OpenDev | AO_ConsoleDev);
  655.  
  656.     ConsoleDevice = (struct Library *) ConsoleIO.io_Device;
  657.  
  658.     Buffered = 0;
  659.     KbdBuffered = 0;
  660.  
  661.     /* set CRMOD on */
  662.     WindowFPuts("\23320h");
  663.  
  664.     Initialized = 1;
  665. }
  666.  
  667. #ifdef AMIFLUSH
  668. /* This routine adapted from AmigaMail IV-37 by Michael Sinz */
  669. static struct Message *
  670. GetFMsg(port)
  671.     struct MsgPort *port;
  672.     {
  673.     struct IntuiMessage *msg,*succ,*succ1;
  674.  
  675.     if(msg=(struct IntuiMessage *)GetMsg(port)){
  676.         if(!flags.amiflush)return(msg);
  677.         if(msg->Class==RAWKEY){
  678.             Forbid();
  679.             succ=(struct IntuiMessage *)(port->mp_MsgList.lh_Head);
  680.             while(succ1=(struct IntuiMessage *)
  681.                  (succ->ExecMessage.mn_Node.ln_Succ)){
  682.                 if(succ->Class==RAWKEY){
  683.                     Remove((struct Node *)succ);
  684.                     ReplyMsg((struct Message *)succ);
  685.                 }
  686.                 succ=succ1;
  687.             }
  688.             Permit();
  689.         }
  690.     }
  691.     return(msg);
  692. }
  693. #endif
  694.